#pragma once

#include "Event.h"

namespace SHGame {
	namespace Events {
		using namespace System;
		using namespace System::Collections::Generic;
		ref class EventQ
		{
		public:
			static int QUEUE_DELAY = 100;
			static EventQ ^EVENTQ = gcnew EventQ();

		private:
			static Dictionary<String^, LinkedList<EventHandler<PropChangeEvent^>^>^>^ listeners = gcnew Dictionary<String^, LinkedList<EventHandler<PropChangeEvent^>^>^>();
			static LinkedList<EventHandler^>^ listeners_all;
			static Queue<Event^>^ Queue = gcnew Queue<Event^>();

		public:
			static void Push(Event^);
			static void AddListener(String^, EventHandler<PropChangeEvent^>^);

		private:
			EventQ(void);

		public:

			void Run() {
				System::Diagnostics::Debug::WriteLine("Running Thread");
				while (true) {
					while (EventQ::Queue->Count > 0) {
						Event^ e = Queue->Dequeue();
						if (e->Args->Property->Equals("sigterm")) {
							System::Diagnostics::Debug::WriteLine("Caught sigterm: exiting event queue thread");
							Threading::Thread::CurrentThread->Abort();
						}
						
						
						//System::Diagnostics::Debug::WriteLine(e+"", "EVENTQ  POP");
						if (listeners->ContainsKey(e->Args->Property)) {
							IEnumerator<EventHandler<PropChangeEvent^>^>^ iter = listeners[e->Args->Property]->GetEnumerator();
							while (iter->MoveNext()) {
								Diagnostics::Debug::Indent();
								iter->Current->Invoke(e->Source, e->Args);
								Diagnostics::Debug::Unindent();
							}
						}
					}
					Threading::Thread::Sleep(QUEUE_DELAY);
				}
			}
		};
	}
}